#include<sys/ipc.h>
#include<sys/sem.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<pthread.h>
#include<time.h>
#include<unistd.h>

extern int errno;
typedef union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           }semun;

void handle_error(const char * info){
    perror(info);
    exit(0);
}

int sem_id;

void * handle_a_quest(void * arg){
    printf("ocupy the sem;\n"); 
    struct sembuf isembuf;
    isembuf.sem_op =  -1;
    isembuf.sem_flg = SEM_UNDO;
    isembuf.sem_num = 0;
    semop(sem_id, &isembuf, 1);
    sleep(20);
    isembuf.sem_op = 1;
    printf("free the sem\n");
    semop(sem_id, &isembuf, 1);
}



int main()
{
    sem_id = semget(0x1275, 1, 0644 | IPC_CREAT);
    if(sem_id == -1)
    {
        handle_error("semget:"); 
    } 
    semun mysemun;
    mysemun.val = 1;   
    // 初始化信号量的值
    if (semctl(sem_id, 0, SETVAL, mysemun) == -1) handle_error("semctl:");

    
    struct sembuf isembuf;
    isembuf.sem_op = -1;
    isembuf.sem_flg = SEM_UNDO;
    isembuf.sem_num = 0;
    pthread_t p;
    pthread_create(&p, 0, handle_a_quest, 0);
    sleep(10);
    printf("quest to the sem;\n");
    if (semop(sem_id, &isembuf, 1) == -1) handle_error("semop");
    printf("successful to get the sem \n");
    // 
    while(1);
    printf("exist");
    
    return 0;
}